﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KS.DataWrapper.DataWrapper
{
    public partial class DataCacheObject<T> : ICollection<T>
    {
        public IEnumerator<T> GetEnumerator()
        {
           if (useLocalCache)
           {
               return nativeCollection.Select(s => s.Value).GetEnumerator();
           }
           else
           {
                return ServiceQuery.GetEnumerator();
           }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            if (useLocalCache)
            {
                return nativeCollection.Select(s => s.Value).GetEnumerator();
            }
            else
            {
                return ServiceQuery.GetEnumerator();
            }
        }

        public void Add(T item)
        {

            Task<T> task = Task.Run(() => CreateItem(item));
            item = task.Result;
            if (useLocalCache)
            {
                item = AddToNativeCollection(task.Result);
            }
        }

        public void AddRange(IEnumerable<T> item)
        {

            Task<IEnumerable<T>> task = Task.Run(() => CreateRangeItem(item));
            item = task.Result;
            if (useLocalCache)
            {
                foreach (var insertItem in item)
                {
                    AddToNativeCollection(insertItem);
                }

            }
        }

        public void Clear()
        {
            ClearNativeCollection();       
        }

        public bool Contains(T item)
        {
            if (useLocalCache)
            {
                return nativeCollection.Contains(new KeyValuePair<dynamic, T>(item.ID, item));
            }
            else
            {
                Task<bool> task = Task.Run(() => ContainsItem(item));
                return task.Result;
            }
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            //throw new NotImplementedException();
        }

        public int Count
        {
            get
            {
                if (useLocalCache)
                {
                    return nativeCollection.Count;
                }
                else
                {
                    Task<long> task = Task.Run(() => ServerCollectionCount());
                    return Convert.ToInt32(task.Result);
                }
               
            }
        }

        public bool IsEmpty
        {
            get
            {
                return nativeCollection.IsEmpty;
            }
        }
        public bool IsReadOnly
        {
            get
            {
                //throw new NotImplementedException();
                return false;
            }
        }

        public ICollection<dynamic> Keys
        {
            get
            {
                return nativeCollection.Keys;
            }
        }

        public bool Remove(T item)
        {
            Task<bool> task = Task.Run(() => DeleteItem(item));
            if (useLocalCache)
            {
                
                return task.Result;
            }
            else
            {
                 return task.Result && RemoveFromNativeCollection(item);
            }

        }


        public void Update(T item)
        {
            Task<T> task = Task.Run(() => UpdateItem(item));
            item = task.Result;
            if (useLocalCache)
            {
                item = UpdateNativeCollection(task.Result);

            }
        }
        public T this[dynamic key]
        {
            get
            {
                if (useLocalCache)
                {
                    return GetElementNativeCollection(key);
                }
                else
                {
                    return GetItemByIdSync(key);
                }
            }
            set
            {
                Task<T> task = Task.Run(() => UpdateItem(value));
                var result = task.Result;
                if (useLocalCache)
                {
                    SetElementNativeCollection(key, result);
                }
            }
        }

       

    }
}
